package com.itheima.AOP;

import com.itheima.mapper.OperateLogMapper;
import com.itheima.pojo.OperateLog;
import com.itheima.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Arrays;

@Component
@org.aspectj.lang.annotation.Aspect
@Slf4j
public class Aspect {
    //·注入请求对象
    @Autowired
    private HttpServletRequest request;

    //拦截增删改的方法 并记录日志

    @Autowired
    private OperateLogMapper operateLogMapper;
    @Around("@annotation(com.itheima.anno.Log)")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        log.info("对增删改记录日志");
        //1.获取操作人id
        //获取请求头中的token
        String token = request.getHeader("token");
        //解析令牌
        Claims claims = JwtUtils.parseJWT(token);
        //获取id
        Integer empId = (Integer)claims.get("id");

        //2.获取操作时间
        LocalDateTime operateTime = LocalDateTime.now();

        //3.获取执行方法的全类名
        String className = pjp.getTarget().getClass().getName();

        //4.获取执行方法名
        String methodName = pjp.getSignature().getName();

        //5.获取方法运行时参数
        Object[] args = pjp.getArgs();
        //把参数转换为字符串
        String methodParams = Arrays.toString(args);

        //6.获取方法运行时返回值
        //记录方法开始
        Long start = System.currentTimeMillis();
        //执行方法
        Object result = pjp.proceed();
        //result可能为空
        String returnValue = result == null ? "空" : result.toString();
        //记录方法结束
        Long end = System.currentTimeMillis();
        //7.获取方法运行耗时
        Long costTime = end - start;
        log.info("操作人id:{},操作时间:{},类名:{},方法名:{},参数:{},返回值:{},耗时:{}",empId,operateTime,className,methodName,methodParams,returnValue,costTime);
        //创建日志对象并封装
        OperateLog operateLog = new OperateLog();
        operateLog.setOperateEmpId(empId);
        operateLog.setOperateTime(operateTime);
        operateLog.setClassName(className);
        operateLog.setMethodName(methodName);
        operateLog.setMethodParams(methodParams);
        operateLog.setReturnValue(returnValue);
        operateLog.setCostTime(costTime);
        //把日志记录到数据库
        operateLogMapper.insert(operateLog);
        return result;

    }
}
